﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Visitor;
using Taste;

namespace ASTClass
{
    class ProcDeclAST : AST
    {
        public ProcDeclAST() : base() { name = "ProcDecl"; }
        public ProcDeclAST(AST parent) : base(parent) { name = "ProcDecl"; }

        public override AST Clone()
        {
            ProcDeclAST ast = new ProcDeclAST();
            ast.operators = operators;
            foreach (AST c in children)
                ast.children.Add(c.Clone());

            return ast;
        }

        public override void  CodeGen(Taste.SymbolTable st, Taste.CodeFileGen cfg)
        {
            //update current scope
            st.OpenScope(this.UniqueName);
            int i = 1;
            foreach (AST child in children)
            {
                if (child.Name == "VarDecl")
                {
                    foreach (AST grandchild in child.Children)
                    {
                        if (grandchild.Name == "Ident")
                        {

                            Var x = new Var(grandchild as IdentAST);
                            st.insertLocalVar(x);
                            i++;
                        }
                    }
                }
            }
            IdentAST ident1 = children[0] as IdentAST;
            int numlocs = st.numLocals(this.UniqueName);
            cfg.AddFuncName(ident1.Value);
            cfg.AddCommand("subu", "$sp, $sp, " + (numlocs + 4) * 4);
            cfg.AddCommand("sw", "$ra, " + (numlocs + 4) * 4 + "($sp)");
            cfg.AddCommand("sw", "$fp, " + (numlocs + 3) * 4 + "($sp)");
            cfg.AddCommand("move", "$fp, $sp");
            for (i = 1; i < children.Count(); i++)
            {
                children[i].CodeGen(st, cfg);
            }
            cfg.AddCommand("lw", "$ra, " + (numlocs + 4) * 4 + "($sp)");
            cfg.AddCommand("lw", "$fp, " + (numlocs + 3) * 4 + "($sp)");
            cfg.AddCommand("addiu", "$sp, $sp, " + (numlocs + 4) * 4);
            cfg.AddCommand("jr", "$ra");
            st.CloseScope();
        }

        #region Visitor pattern

        public override void Accept(IVisitor visitor)
        {
            visitor.Visit(this);
        }

        #endregion Visitor pattern
    }
}
